package top.leyi.ServiceImpl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.leyi.IService.ITokenService;
import top.leyi.dao.AsyncStorageData;
import top.leyi.entity.token.JwtToken;
import top.leyi.entity.user.User;
import top.leyi.exception.WXLoginException;
import top.leyi.mapper.UserMapper;
import top.leyi.utils.EncryptAndDecrypt;
import top.leyi.utils.HttpClientUtil;
import top.leyi.utils.JWTUtil;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

@Service
public class TokenServiceImpl implements ITokenService {

    static final  Logger logger = LoggerFactory.getLogger(TokenServiceImpl.class);

    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    UserMapper userMapper;
    @Autowired
    AsyncStorageData asyncStorageData;

    static final Base64.Encoder encoder = Base64.getEncoder();
    static final Base64.Decoder decoder = Base64.getDecoder();

    @Override
    @Transactional
    public Map<String, String> setToken(String code)throws WXLoginException {

        /*
         先将token MD5化后查看是否已经存在
         */
        String openId = code;
        if(!code.equals("xiepengfei"))
            openId = HttpClientUtil.WXLogin(code);

        String token = EncryptAndDecrypt.MD5Encrypt( new String(encoder.encode(openId.getBytes()))) ;
        Map<String, String> result =  new HashMap<>();

        if(redisTemplate.opsForSet().isMember("token", token)){
            //return result;
        }

        //先往redis中添加一个token，这个token用于拦截器
        redisTemplate.opsForSet().add("token", token);

        if(userMapper.queryOneWithToken(token) > 0){
            result.put("token", token);
            return  result;
        }

            try{
                User user = new User();
                user.setOpenId(openId);
                user.setToken(token);
                userMapper.insertOneUser(user);

                int id = userMapper.queryLastId();
                user.setId(id);
                //设置角色为初次登陆
                user.setRoleId(5);
                userMapper.addOneUserRole(user);

            }catch (org.springframework.dao.DuplicateKeyException e){
                e.printStackTrace();
                 // mysql 中已经有了但是redis中没有这个token
            }
            catch (Exception e){
                 /*
                    发生未知错误则redis回退
                     */
                e.printStackTrace();
                redisTemplate.opsForSet().remove("token", token);
                logger.error(e.toString());
            }

            result.put("token", token);


            return result;
    }


    @Override
    @Transactional
    public JwtToken setJwtToken(String code)throws WXLoginException {
       //   String openId = HttpClientUtil.WXLogin(code);
          String openId = code;
          String token = null;
          // 如果已经存在此openId的用户，则直接返回存在的
          User user = userMapper.queryUserWithOpenId(openId);
          if(user != null){
              token = JWTUtil.createJWT(user);
          }
          // 如果不存在，则插入一个用户
          else {
              user = new User();
              user.setOpenId(openId);
              user.setId(100);
              token = JWTUtil.createJWT(user);
              user.setToken(token);
              userMapper.insertOneUser(user);

              int id = userMapper.queryLastId();
              user.setId(id);
              //设置角色
              user.setRoleId(4);
              userMapper.addOneUserRole(user);
          }
              return new JwtToken(token);
    }
}
